package system.back;

import java.util.*;

import system.struct.ParserResult;

/**
 * Parser of system
 * <p>
 * Parse a given <i>Query</i> using loaded information (<tt>Loader</tt> info)
 * and return <tt>ParserResult</tt> for later processing
 * 
 * @author Jack
 * 
 */
public class Parser {
	Loader info;

	/**
	 * Constructs a <tt>Parser</tt> using given loaded information (
	 * <tt>Loader</tt> info)
	 * 
	 * @param info
	 *            loaded information
	 */
	public Parser(Loader info) {
		this.info = info;
	}

	/**
	 * Returns parsed information as a <tt>ParserResult</tt> of given
	 * <i>Query</i>
	 * <p>
	 * this implementation uses longest-match strategy, i.e. the longest
	 * concepts are the first to be matched.
	 * 
	 * @param query
	 *            given <i>Query</i>
	 * @return parsed information as a <tt>ParserResult</tt>
	 */
	public ParserResult parse(String query) {
		query = query.toLowerCase();
		String[] terms = query.split(" ");
		int length = terms.length;
		int max = length;
		while (max != 0) {
			for (int i = 0; i + max <= length; i++) {
				String test = rebuild(terms, i, i + max);
				if (info.hasCnpt(test)/* && (max > 1 || !info.hasInst(test)) */) {
					System.out.println("Matched concepts: " + test);
					test += "\t";
					terms[i] = test;
					for (int j = i + max; j < length; j++) {
						terms[j - max + 1] = terms[j];
					}
					length = length - max + 1;
				}
			}
			max--;
		}
		ArrayList<String> cnpt = new ArrayList<String>();
		String keywords = "";
		for (int i = 0; i < length; i++) {
			if (terms[i].indexOf("\t") != -1) {
				cnpt.add(terms[i].replaceAll("\\t", ""));
			} else {
				keywords += terms[i] + " ";
			}
		}
		keywords = keywords.trim();
		String[] cnptList = new String[0];
		cnptList = cnpt.toArray(cnptList);
		ParserResult pr = new ParserResult(keywords, cnptList);
		return pr;
	}

	/**
	 * Returns a rebuilded <tt>String</tt> connected by <i>Space</i>, using
	 * [start, end) style
	 * 
	 * @param terms
	 *            <tt>String</tt>s
	 * @param start
	 *            start index
	 * @param end
	 *            end index
	 * @return rebuilded <tt>String</tt> connected by <i>Space</i>
	 */
	private String rebuild(String[] terms, int start, int end) {
		String ans = "";
		for (int i = start; i < end; i++) {
			if (i == start)
				ans += terms[i];
			else
				ans += " " + terms[i];
		}
		return ans;
	}
}
